﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
using TomNet.Data;
using TomNet.Entity;

namespace TomNet.AspNetCore
{
    public class ErrorHandlerMiddleware
    {

        private readonly RequestDelegate _next;


        public ErrorHandlerMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                var statusCode = context.Response.StatusCode;

                if (statusCode != 200)
                {
                    await HandleExceptionAsync(context, statusCode, ex.Message);
                }
            }
            finally
            {
                var statusCode = context.Response.StatusCode;
                var msg = "";
                if (statusCode == 401)
                {
                    msg = "未授权";
                    statusCode = ApiResultCode.PermissionNoAccess;
                }
                else if (statusCode == 404)
                {
                    msg = "未找到服务";
                    statusCode = ApiResultCode.InterfaceAddrInvalid;
                }
                else if (statusCode == 502)
                {
                    msg = "请求错误";
                    statusCode = ApiResultCode.InterfaceForbidden;
                }
                else if (statusCode != 200)
                {
                    // 400 错误
                    // 比如入参由API默认规则去监测的，那么暂时还不知道如何拦截这个错误
                    // 因为这里就算拦截了，那么下面在修改相应输出的时候，会异常，因为系统已经将错误发给客户端了
                    msg = "未知错误";
                    statusCode = ApiResultCode.SystemInnerError;
                }
                if (!string.IsNullOrWhiteSpace(msg))
                {
                    await HandleExceptionAsync(context, statusCode, msg);
                }
            }
        }
        //异常错误信息捕获，将错误信息用Json方式返回
        private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg)
        {
            var result = JsonConvert.SerializeObject(
                new OpResult<string>()
                {
                    Success = false,
                    Msg = msg,
                    StatusCode = ApiResultCode.PermissionNoAccess
                });
            context.Response.StatusCode = 200;
            context.Response.ContentType = "application/json;charset=utf-8";
            return context.Response.WriteAsync(result);
        }
    }

    //扩展方法
    public static class ErrorHandlerMiddlewareExtensions
    {
        public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ErrorHandlerMiddleware>();
        }
    }
}
